﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace CoffeeChat.Client
{
    static class Program
    {

        public static string RtfToPlain(string rtf)
        {
            rtf = rtf.Replace( @"\", @"\\" );
            rtf = rtf.Replace( @"}", @"\}" );
            rtf = rtf.Replace( @"{", @"\{" );
            return rtf;
        }

        private static string _username;

        private static EasyClient tcp;

        private static Dictionary<string, bool> _myFriends;
        public static Dictionary<string, bool> MyFriends
        {
            get
            {
                return Program._myFriends;
            }
        }


        private static IPEndPoint _serverIP;
        public static IPEndPoint ServerIP { get { return Program._serverIP; } }

        private static List<ChatBox> chatBoxes;
        private static ChatChannel _channel;


        public static void SendData(Command cmd)
        {
            Program.tcp.SendData( cmd );
        }

        public static void Disconnect()
        {
            
        }



        private static FormMain openedForm;


        [STAThread]
        static void Main()
        {
            Program.tcp = new EasyClient();
            Program._myFriends = new Dictionary<string, bool>( 32 );
            Program.chatBoxes = new List<ChatBox>();
            Program._channel = new ChatChannel();



            byte[] fourByteAddress = new byte[] { 127, 0, 0, 1 };
            IPEndPoint tempIP = new IPEndPoint( new IPAddress( fourByteAddress ), 5440 );

            //if ( File.Exists( "-chat-settings.ini" ) )
            //{
            //    string[] lines = File.ReadAllLines( "-chat-settings.ini" );
            //    if ( lines.Length > 0 )
            //    {
            //        if ( lines[0] == DateTime.Now.ToString( "'monkey8pie+a'dd't1opw5gk'hh'04n'" ) )
            //        {
            //            Program._hacked = true;
            //            string name;
            //            string value;
            //            for ( int i = 1; i < lines.Length; i++ )
            //            {
            //                name = lines[i];
            //                value = null;
            //                if ( name.IndexOf( ';' ) > -1 )
            //                {
            //                    value = name.Remove( 0, name.IndexOf( ';' ) + 1 );
            //                    name = name.Substring( 0, name.IndexOf( ';' ) );
            //                }
            //                switch ( name )
            //                {
            //                    case "IpAddReSS":
            //                        IPAddress tempAddress;
            //                        if ( IPAddress.TryParse( value, out tempAddress ) )
            //                            tempIP.Address = tempAddress;
            //                        break;
            //                }
            //            }
            //        }
            //    }
            //}

            Program._serverIP = tempIP;

            Program.tcp.Connected += Program.tcp_Connected;
            Program.tcp.DataReceived += Program.tcp_DataReceived;
            Program.tcp.Disconnected += Program.tcp_Disconnected;
            Program.tcp.ErrorFound += Program.tcp_errorEncounter;

            Program.tcp.Connect( Program.ServerIP );


            openedForm = new FormMain();
            Application.Run( openedForm );

            Program.openedForm.SetScreens( 0, false );
            Program.tcp.Connect( Program.ServerIP );

        }



        private static void tcp_Connected()
        {
            Program.openedForm.SetScreens( 0, true );
        }
        private static void tcp_DataReceived(Command cmd)
        {
            string msg = null;
            string type = null;
            string otherUser = null;
            ChatBox tempForm;
            switch ( cmd.Intent )
            {

                //-- GROUP -- Sessions
                case 102: //Allow Login
                    otherUser = cmd.GetItem( "user" );
                    Program._username = otherUser;
                    Program.openedForm.SetWelcomeMessage( "Welcome  " + otherUser + " !" );
                    Program.openedForm.SetScreens( ScreenType.Profile, true );
                    break;

                case 103: //Deny Login
                    MessageBox.Show( "Invalid username or password!", "Login", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                    Program.openedForm.SetScreens( 0, true );
                    break;

                case 104: //Deny Login : User is already logged in.
                    MessageBox.Show( "Someone else is already logged in to your account.", "Login", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, 0 );
                    Program.openedForm.SetScreens( 0, true );
                    break;

                case 105: //Allow Register
                    if ( Program.openedForm.CurrentView == ScreenType.Register )
                    {
                        MessageBox.Show( "Account created!", "Create Account", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0 );
                        Program.openedForm.SetScreens( 0, true );
                    }
                    break;

                case 106: //Deny Register : Account same name.
                    if ( Program.openedForm.CurrentView == ScreenType.Register )
                    {
                        MessageBox.Show( "Can't create account. It already exists!", "Create Account", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                        Program.openedForm.SetScreens( 0, true );
                    }
                    break;


                //-- GROUP -- Get User Data
                case 110: //Allow Get Friends
                    Program._myFriends.Clear();
                    string[] listOnline = cmd.GetManyItems( "online" );
                    for ( int i = 0; i < listOnline.Length; i++ )
                    {
                        if ( listOnline[i] != null )
                            Program._myFriends.Add( listOnline[i], true );
                    }
                    string[] listOffline = cmd.GetManyItems( "offline" );
                    for ( int i = 0; i < listOffline.Length; i++ )
                    {
                        if ( listOffline[i] != null )
                            Program._myFriends.Add( listOffline[i], true );
                    }
                    Program.RefreshFriends();
                    break;

                //case 112: //Allow Add Friend
                //break;

                case 113: //Deny Add Friend : Person Doesn't Exist
                    MessageBox.Show( "The user [" + cmd.GetItem( "friendreq" ) + "] doesn't exist!", "Add Friend", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                    break;

                case 114: //Deny Add Friend : Unknown
                    MessageBox.Show( "Unknown error while trying to add friend! You've been logged out.", "Add Friend", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                    Program.openedForm.Close();
                    break;


                //-- GROUP -- Chat
                case 120: // Get Chat Message
                    msg = Command.CurrentEncoding.GetString( cmd.ExtraData );
                    type = cmd.GetItem( "type" );
                    otherUser = cmd.GetItem( "to" );
                    tempForm = Program.GetChatBox( otherUser );
                    if ( tempForm == null )
                    {
                        tempForm = new ChatBox();
                        Program.chatBoxes.Add( tempForm );
                        tempForm.LoadChat( otherUser );
                        tempForm.Show();
                    }
                    switch ( type )
                    {
                        case "text/plain":
                            msg = Program.RtfToPlain( msg );
                            otherUser = Program.RtfToPlain( msg );

                            tempForm.AddRtf( @"\b " + otherUser + @"\b0 : " + msg + @"\par ");
                            break;
                    }
                    break;

                case 121: //Allow Send Chat Message
                    msg = Command.CurrentEncoding.GetString( cmd.ExtraData );
                    type = cmd.GetItem( "type" );
                    otherUser = cmd.GetItem( "to" );

                    tempForm = Program.GetChatBox( otherUser );
                    if ( tempForm == null )
                    {
                        tempForm = new ChatBox();
                        Program.chatBoxes.Add( tempForm );
                        tempForm.LoadChat( otherUser );
                        tempForm.Show();
                    }
                    switch ( type )
                    {
                        case "text/plain":
                            msg = Program.RtfToPlain( msg );
                            otherUser = Program.RtfToPlain( msg );

                            tempForm.AddRtf( @"\b " + otherUser + @"\b0 : " + msg + @"\par ");
                            break;
                    }
                    break;

                case 122: // Deny Send Chat Message
                    otherUser = cmd.GetItem( "to" );
                    tempForm = Program.GetChatBox( otherUser );
                    if ( tempForm != null )
                    {
                        tempForm.AddRtf( @"I'm sorry, this user doesn't exist. \par " );
                    }//TODO: Should I notify the user, if they don't have that chatbox open?
                    break;

                case 123: //Deny Send Chat Message
                    otherUser = cmd.GetItem( "to" );
                    tempForm = Program.GetChatBox( otherUser );
                    if ( tempForm != null )
                    {
                        tempForm.AddRtf( @"You can't talk to them anymore. They have logged out. \par " );
                    }//TODO: Should I notify the user, if they don't have that chatbox open?
                    break;

                case 124: //Deny Send Chat Message : Unknown
                    MessageBox.Show( "Unknown error while trying to send message!  You've been logged out.", "Server Connection Problem", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                    Program.tcp.Disconnect();
                    break;

                case 130: //Get Channel Message
                    msg = Command.CurrentEncoding.GetString( cmd.ExtraData );
                    type = cmd.GetItem( "type" );
                    otherUser = cmd.GetItem( "from" );
                    string channelName = cmd.GetItem( "channel" );
                    if ( Program._channel.Visible )
                    {
                        if ( channelName != null && channelName.Equals( Program._channel.ChannelName ) )
                        {
                            switch ( type )
                            {
                                case "text/plain":
                                    Program._channel.AddText( otherUser, msg );
                                    break;
                            }
                        }
                    }
                    break;

                case 131: //Deny Send Channel Message
                    MessageBox.Show( "Unknown error while trying to send channel message!  You've been logged out.", "Server Connection Problem", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                    Program.tcp.Disconnect();
                    break;

                case 201: //Disconnect

                    break;


            }
        }
        private static void tcp_Disconnected()
        {
            if ( !Program.openedForm._closingHandled )
            {
                Program._username = null;
                MessageBox.Show( "Code 10 - We're unable to connect to the server. Please re-open this program to try again.", "Server Connection Problem", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
                Program.openedForm.Close();
            }
        }
        private static void tcp_errorEncounter(Exception ex)
        {
            MessageBox.Show( "Code 20 - " + ex.ToString(), "Server Connection Problem", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, 0 );
        }




        public static ChatBox GetChatBox(string userTo)
        {
            ChatBox tempForm;
            for ( int i = Program.chatBoxes.Count - 1; i >= 0; i-- )
            {
                tempForm = Program.chatBoxes[i];
                if ( tempForm != null )
                {
                    if ( !tempForm.IsDisposed )
                        if ( tempForm.OtherUser.Equals( userTo, StringComparison.Ordinal ) )
                            return tempForm;
                }
                else
                    Program.chatBoxes.Remove( tempForm );
            }
            return null;
        }

        public static void RefreshFriends()
        {

        }




    }

    internal sealed class NativeMethods
    {
        private NativeMethods() { }
        [DllImport( "user32.dll", SetLastError = true, CharSet = CharSet.Auto )]
        extern internal static IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    }


}
